home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / biblio / bibtex / utils / bibsort / bibsort.sh < prev    next >
Linux/UNIX/POSIX Shell Script  |  1992-10-12  |  5KB  |  164 lines

  1. #!/bin/sh
  2. ### ====================================================================
  3. ###  @UNIX-shell-file{
  4. ###     author          = "Nelson H. F. Beebe",
  5. ###     version         = "0.00",
  6. ###     date            = "13 October 1992",
  7. ###     time            = "19:33:14 MDT",
  8. ###     filename        = "bibsort.sh",
  9. ###     address         = "Center for Scientific Computing
  10. ###                        Department of Mathematics
  11. ###                        University of Utah
  12. ###                        Salt Lake City, UT 84112
  13. ###                        USA",
  14. ###     telephone       = "+1 801 581 5254",
  15. ###     FAX             = "+1 801 581 4148",
  16. ###     checksum        = "35811 163 700 5138",
  17. ###     email           = "beebe@math.utah.edu (Internet)",
  18. ###     codetable       = "ISO/ASCII",
  19. ###     keywords        = "bibliography, sorting, BibTeX",
  20. ###     supported       = "yes",
  21. ###     docstring       = "This file contains the bibsort utility, a
  22. ###                        program for sorting BibTeX data base files
  23. ###                        by their BibTeX tag names.
  24. ###
  25. ###                        The checksum field above contains a CRC-16
  26. ###                        checksum as the first value, followed by the
  27. ###                        equivalent of the standard UNIX wc (word
  28. ###                        count) utility output of lines, words, and
  29. ###                        characters.  This is produced by Robert
  30. ###                        Solovay's checksum utility.",
  31. ###  }
  32. # ====================================================================
  33. # Sort a BibTeX file fragment by citation tags, filtering stdin to
  34. # stdout.
  35. #
  36. # Usage:
  37. #       bibsort [optional sort(1) switches] <infile >outfile
  38. #
  39. # If the sort switches are omitted, -f (ignore letter case
  40. # differences) is used.  "bibsort -f -u" would remove duplicate
  41. # bibliography entries from the input stream.
  42. #
  43. # Note that this operation cannot be done in general, because @string
  44. # and @preamble entries need to come first, and cross-references last.
  45. #
  46. # In general, you should only apply this command to a fragment of a
  47. # .bib file that you know in advance can be sorted.
  48. #
  49. # We deal with leading commentary, @preamble, and @string by giving
  50. # them temporary sort keys that place them before other bibliography
  51. # entries.
  52. #
  53. ########################################################################
  54. # WARNINGS:
  55. #
  56. # (1) This simple version does NOT recognize bib entries with outer
  57. # parentheses instead of braces.
  58. #
  59. # (2) It may fail on some UNIX sort implementations that cannot handle
  60. # very long lines, because for sorting purposes, each complete bib
  61. # entry is temporarily folded into a single line.  You may be able to
  62. # overcome this problem by adding a -z nnnnn switch to the sort
  63. # command to set the maximum line size to nnnnn bytes.
  64. #
  65. ########################################################################
  66. #
  67. # The sorting is implemented as a filter pipeline:
  68. #
  69. # Stage 1 (nawk) finds bib file entries and prefixes them with a line
  70. # containing a sort key, where each such line begins with a Ctl-E, and
  71. # the file ends with Ctl-E.
  72. #
  73. # Stage 2 (tr) turns LF into Ctl-G and Ctl-E into LF.  This hides
  74. # line boundaries and makes each item a separate `line'.
  75. #
  76. # Stage 3 (sort) sorts `lines' (i.e. bib entries), ignoring
  77. # letter case differences.
  78. #
  79. # Stage 4 (tr) turns LF into Ctl-E, and Ctl-G back into LF.  This
  80. # restores the original line boundaries.
  81. #
  82. # Stage 5 (tr) deletes all Ctl-E and Ctl-F characters.
  83. #
  84. # Stage 6 (egrep) removes the sort key lines.
  85. #
  86.  
  87. if [ $# -gt 0 ]
  88. then
  89.     SORTFLAGS="$*"
  90. else
  91.     SORTFLAGS="-f"
  92. fi
  93.  
  94. nawk '
  95. BEGIN {
  96.         sort_prefix = "\005"
  97.         sort_key = sort_prefix "%%SORTKEY:"
  98.         hidden_newline = "\006"
  99.         print sort_key "\001" hidden_newline
  100. }
  101.  
  102. /^@[Pp][Rr][Ee][Aa][Mm][Bb][Ll][Ee]{/ {
  103.         k = index($0,"{") + 1
  104.         print sort_key "\002" substr($0,k) hidden_newline
  105.         printbraceditem()
  106.         next
  107. }
  108. /^@[sS][tT][rR][iI][nN][gG]{/ {
  109.         k = index($0,"{") + 1
  110.         m = index($0,"=")
  111.         print sort_key "\003" substr($0,k,m-k) hidden_newline
  112.         printbraceditem()
  113.         next
  114. }
  115.  
  116. # "@keyword{tag,"
  117. /^@[a-zA-Z0-9]*{/       {
  118.         k = index($0,"{") + 1
  119.         m = index($0,",")
  120.         print sort_key "\004" substr($0,k,m-k) hidden_newline
  121.         print
  122.         next
  123. }
  124.  
  125. { print }
  126.  
  127. END { printf(sort_prefix) }
  128.  
  129. function bracecount(s, k,n)
  130. {
  131.     n = 0
  132.     for (k = 1; k <= length(s); ++k)
  133.     {
  134.         if (substr(s,k,1) == "{")
  135.             n++
  136.         else if (substr(s,k,1) == "}")
  137.             n--
  138.     }
  139.     return (n)
  140. }
  141.  
  142. # Starting with the current contents of $0, print lines until we
  143. # reach a zero brace count.
  144.  
  145. function printbraceditem(count)
  146. {
  147.     count = bracecount($0)
  148.     print $0
  149.     while (count != 0)
  150.     {
  151.         if (getline <= 0)
  152.             break
  153.         printf("%s\007",$0)
  154.         count += bracecount($0)
  155.     }
  156. }
  157. ' | \
  158.         tr '\012\005' '\007\012' | \
  159.         sort ${SORTFLAGS} | \
  160.         tr '\007\012' '\012\005' | \
  161.         tr -d '\005\006' | \
  162.         egrep -v  '^%%SORTKEY:'
  163. ################################[The End]###############################
  164.